package com.zxhhyj.music.logic.utils

import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import android.os.ParcelFileDescriptor
import android.provider.MediaStore
import com.kyant.taglib.TagLib
import com.zxhhyj.music.logic.bean.SongBean
import com.zxhhyj.music.logic.config.coverFilesDir
import com.zxhhyj.music.logic.repository.SettingRepository
import java.io.File
import java.io.FileOutputStream


private fun createSongBean(data: String, id: Long?): SongBean? {
    val songFile = File(data)
    val fd = ParcelFileDescriptor.open(songFile, ParcelFileDescriptor.MODE_READ_ONLY)
    val metadata =
        TagLib.getMetadata(fd.dup().detachFd(), readPictures = true) ?: return null

    val songName =
        metadata.propertyMap["TITLE"]?.getOrNull(0)?.trim()
            ?: songFile.name.substringBeforeLast(".")
    val album = metadata.propertyMap["ALBUM"]?.getOrNull(0)?.trim()
    val artist = metadata.propertyMap["ARTIST"]?.getOrNull(0)?.trim()
    val lyric = metadata.propertyMap["LYRICS"]?.getOrNull(0)?.trim()
        ?: runCatching {
            if (SettingRepository.EnableReadExternalLyrics) {
                File("${songFile.path.substringBeforeLast(".")}.lrc").readText()
            } else {
                null
            }
        }.getOrNull()
    val encoder = metadata.propertyMap["ENCODER"]?.getOrNull(0)?.trim()
    val genre = metadata.propertyMap["GENRE"]?.getOrNull(0)?.trim()
    val duration = metadata.audioProperties.length.toLong()
    val bitrate = metadata.audioProperties.bitrate
    val channels = metadata.audioProperties.channels
    val sampleRate = metadata.audioProperties.sampleRate
    val coverFile = metadata.pictures.getOrNull(0)?.data?.let {
        BitmapFactory.decodeByteArray(it, 0, it.size)
    }?.let {
        runCatching {
            val file = File(coverFilesDir, songName)
            val fos = FileOutputStream(file)
            it.compress(Bitmap.CompressFormat.JPEG, 100, fos)
            fos.flush()
            fos.close()
            file
        }.getOrNull()
    }
    fd.close()
    return SongBean(
        coverUrl = coverFile?.path,
        albumName = album,
        artistName = artist,
        duration = duration,
        data = data,
        dateModified = songFile.lastModified(),
        songName = songName,
        size = songFile.length(),
        id = id,
        bitrate = bitrate,
        samplingRate = sampleRate,
        lyric = lyric,
        channels = channels,
        encoder = encoder,
        genre = genre
    )
}

fun File.toSongBean(): SongBean? {
    return createSongBean(path, null)
}

fun Cursor.toSongBean(): SongBean? {
    val dataIndex = getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
    val idIndex = getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
    val data = getString(dataIndex)
    val id = getLong(idIndex)
    return createSongBean(data, id)
}